﻿using System;
using System.Globalization;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Web;

using System.Xml.Serialization;
using System.Collections;

namespace VTCeBank.SSO.Utils
{

    /// <summary>
    /// 
    /// </summary>

    [Serializable]
    public partial class Account
    {
        HttpRequest httpRequest;

        public bool CheckCookieSSOSession()
        {
            var ssosession = string.Format("{0}", HttpContext.Current.Session["ssosession"] ?? "");
            if (ssosession.Split('.').Length < 2) return false;

            return ssosession.Split('.')[1] == AccountID;
        }


        public string GetKeyFromSSOServer(string keyTripleDES)
        {
          
            return HttpHelper.GetStringHttpResponse(string.Format("{0}/accounts/sso/KeyGenerate.ashx?serviceID={1}&secretKey={2}&keyTripleDES={3}", Constants.SSO_SERVER, Constants.SERVICE_PROVIDER_SITE_ID, Constants.SSO_SECRET_KEY, keyTripleDES));
        }

        public string GetKeyFromFaceServer(string keyTripleDES)
        {
         //   return HttpHelper.GetStringHttpResponse(string.Format("{0}/accounts/sso/KeyGenerate.ashx?serviceID={1}&secretKey={2}&keyTripleDES={3}", Constants.SSO_SERVERFacebook, Constants.SERVICE_PROVIDER_SITE_ID, Constants.SSO_SECRET_KEY, keyTripleDES));
            
            // duoi local thi return kieu nay, thay doi khi trien khai len server that
            return HttpHelper.GetStringHttpResponse(string.Format("{0}/socialapi/sso/KeyGenerate.ashx?serviceID={1}&secretKey={2}&keyTripleDES={3}", Constants.SSO_SERVERFacebook, Constants.SERVICE_PROVIDER_SITE_ID, Constants.SSO_SECRET_KEY, keyTripleDES));
        }

        public string GetAccessToken(string requestToken)
        {
            if (Constants.SSO_SERVER.Contains("https://go.vn"))
            return HttpHelper.GetStringHttpResponse(string.Format("{0}/accounts/pages/public/AccessToken.ashx?serviceId={1}&accountName={2}&requestToken={3}", Constants.SSO_SERVER, Constants.SERVICE_PROVIDER_SITE_ID, HttpUtility.UrlEncode(AccountName), HttpUtility.UrlEncode(requestToken)));
            else
            return HttpHelper.GetStringHttpResponse(string.Format("{0}/accounts/public/AccessToken.ashx?serviceId={1}&accountName={2}&requestToken={3}", Constants.SSO_SERVER, Constants.SERVICE_PROVIDER_SITE_ID, HttpUtility.UrlEncode(AccountName), HttpUtility.UrlEncode(requestToken)));
        }

        public string GetAccessTokenWithBalance(string requestToken)
        {
            return HttpHelper.GetStringHttpResponse(string.Format("{0}/accounts/public/AccessToken.ashx?requestAccountBalance=true&serviceId={1}&accountName={2}&requestToken={3}", Constants.SSO_SERVER, Constants.SERVICE_PROVIDER_SITE_ID, HttpUtility.UrlEncode(AccountName), HttpUtility.UrlEncode(requestToken)));
        }

        public AccountInfo GetAccountInfor()
        {
            return GetAccountInfor(AccessToken);

        }
        private AccountInfo GetAccountInfor(string accessToken)
        {
            if (string.IsNullOrEmpty(accessToken)) return new AccountInfo();

            return (AccountInfo)XMLUtility.FromXml(HttpHelper.GetStringHttpResponse(string.Format("{0}/accounts/public/accountinfo.ashx?serviceId={1}&accessToken={2}", Constants.SSO_SERVER, Constants.SERVICE_PROVIDER_SITE_ID, HttpUtility.UrlEncode(accessToken))),
                typeof(AccountInfo));

        }

        private string accessToken;
        public string AccessToken
        {
            get
            {
                // GET Access Token for Payment
                string requestToken = httpRequest["requestToken"];
                if (requestToken != null && string.IsNullOrEmpty(accessToken))
                {
                    //LoggerHelper.LogMessage("GetAccessToken");
                    accessToken = GetAccessToken(requestToken);

                }

                return accessToken;

            }

        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Account"/> class.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="type"></param>
        public Account(HttpRequest request,int type)
        {
            if (request == null) return;
            httpRequest = request;
            if (!IsLogin) return;

            // Cần thực hiện Replace(" ", "+") do việc mã hóa
            string data = HttpUtility.UrlDecode(httpRequest.QueryString[Constants.RESPONSE_UD].ToString()).Replace(" ", "+");
           // LoggerHelper.LogMessage("Data:" + data);
            string dataDecrypt = string.Empty;
            int count = 0;
            //Decrypt user data, Constants.KEY= "KEY_ENCRYPT_DECRYPT"
            try
            {
                while (string.IsNullOrEmpty(dataDecrypt) && count < 3)
                {
                    System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();
                    string ssoKeyTripleDes = type == 1 ? SSOHelper.GetSSOKey() : SSOHelper.GetSSOKeyFace();
                  
                    // Trường hợp chưa có key mã hóa, get key mã hóa từ SSO);
                    if (string.IsNullOrEmpty(ssoKeyTripleDes))
                    {
                        if (type == 1)
                        {
                          //  LoggerHelper.LogMessage("step1:");
                            ssoKeyTripleDes = GetKeyFromSSOServer(SSOHelper.GetSSOKey());
                            SSOHelper.SetSSOKey(ssoKeyTripleDes);
                          //  LoggerHelper.LogMessage("end1:" + ssoKeyTripleDES);
                        }
                        else
                        {
                           // LoggerHelper.LogMessage("step2:");
                            ssoKeyTripleDes = GetKeyFromFaceServer(SSOHelper.GetSSOKey());
                            SSOHelper.SetSSOKeyFace(ssoKeyTripleDes);
                            //LoggerHelper.LogMessage("end2:" + ssoKeyTripleDES);
                        }
                        //ssoKeyTripleDES = GetKeyFromGOServer(SSOHelper.GetSSOKey());
                        SSOHelper.SetSSOKey(ssoKeyTripleDes);
                    }

                    dataDecrypt = Security.TripleDESDecrypt(ssoKeyTripleDes, data);
                  //  LoggerHelper.LogMessage("step3:" + dataDecrypt);
                    // Truong hop k giai mã được dữ liệu -> key mã hóa bị thay đổi, tiến hành lấy lại key mã hóa
                    if (string.IsNullOrEmpty(dataDecrypt))
                    {
                        if (type == 1)
                        {
                            ssoKeyTripleDes = GetKeyFromSSOServer(SSOHelper.GetSSOKey());
                            SSOHelper.SetSSOKey(ssoKeyTripleDes);
                        }
                        else
                        {
                            ssoKeyTripleDes = GetKeyFromFaceServer(SSOHelper.GetSSOKey());
                            SSOHelper.SetSSOKeyFace(ssoKeyTripleDes);
                        }
                       
                        dataDecrypt = Security.TripleDESDecrypt(ssoKeyTripleDes, data);
                    }
                    count++;
                }

                GetData(dataDecrypt);
            }
            catch (Exception ex)
            {
                LoggerHelper.LogMessage("Exception:" + ex.Message);
                throw;
            }

            //Checking if time is 30s late then return no regular
            if (DateTime.Compare(Convert.ToDateTime(LoginTime, new CultureInfo("en-US")).AddSeconds(Int32.Parse(Constants.SSO_TIMEOUT)), DateTime.Now) < 0)
            {
                // Invalid time out, reset Account Info
                AccountID = "-99";
                AccountName = string.Empty;
            }


        }

        /// <summary>
        ///    Classed used to bypass self-signed server certificate
        /// </summary>
        /// <remarks>
        ///     
        /// </remarks>
        public class TrustAllCertificatePolicy : System.Net.ICertificatePolicy
        {
            public TrustAllCertificatePolicy()
            { }

            public bool CheckValidationResult(ServicePoint sp,
              X509Certificate cert, WebRequest req, int problem)
            {
                return true;
            }
        }

        /// <summary>
        /// Gets the data.
        /// </summary>
        /// <param name="userInfo">The user info.</param>
        void GetData(string userInfo)
        {

            userInfo = userInfo + "|||";
            if (userInfo.Split('|').Length < 4)
            {
                return;
            }

            
                AccountID = userInfo.Split('|')[0] ?? "-99";

                AccountName = userInfo.Split('|')[1] ?? string.Empty;

                LoginTime = userInfo.Split('|')[2] ?? string.Empty;

                IPAdress = userInfo.Split('|')[3] ?? string.Empty;

                FacebookId = userInfo.Split('|')[4] ?? string.Empty;

                Status = userInfo.Split('|')[5] ?? string.Empty;

                Email = userInfo.Split('|')[6] ?? string.Empty;
            
        }


        /// <summary>
        /// Gets a value indicating whether this instance is login.
        /// </summary>
        /// <value><c>true</c> if this instance is login; otherwise, <c>false</c>.</value>
        public bool IsLogin
        {
            get { return httpRequest.QueryString[Constants.RESPONSE_S] != null ? httpRequest.QueryString[Constants.RESPONSE_S].ToString() == "1" : false; }
        }

        /// <summary>
        /// Gets the return URL.
        /// </summary>
        /// <value>The return URL.</value>
        public string ReturnURL
        {
            get { return httpRequest.QueryString[Constants.RESPONSE_UR] != null ? HttpUtility.UrlDecode(httpRequest.QueryString[Constants.RESPONSE_UR].ToString()) : "~/"; }
        }

        /// <summary>
        /// Gets or sets the username.
        /// </summary>
        /// <value>The username.</value>
        public string AccountName
        {
            get;
            set;
        }


        /// <summary>
        /// Gets or sets the username.
        /// </summary>
        /// <value>The username.</value>
        public string Email
        {
            get;
            set;
        }
        /// <summary>
        /// Gets or sets the login time.
        /// </summary>
        /// <value>The login time.</value>
        public string LoginTime
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the IP adress.
        /// </summary>
        /// <value>The IP adress.</value>
        public string IPAdress
        {
            get;
            set;
        }

        public string FacebookId
        {
            get;
            set;
        }
        public string Status
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the userid.
        /// </summary>
        /// <value>The userid.</value>
        public string AccountID
        {
            get;
            set;
        }

    }
}
